# vim:set ft= ts=4 sw=4 et fdm=marker:

use Test::Nginx::Socket::Lua;

plan tests => repeat_each() * (blocks() * 3);

our $http_config = <<'_EOC_';
    lua_package_path "${prefix}../../script/?.ljbc;${prefix}../../script/?.lua;;";
_EOC_

no_long_string();

run_tests();

__DATA__


=== TEST 1: httparg - validate query
--- http_config eval: $::http_config
--- config
    location = /t {
        content_by_lua_block {
            local tag  = require("shared.httparg").tag()

            local ARGS = {
                -- 取得 query args object
                _query = tag.query(),

                -- 取得 query args 原始值
                _raw   = tag.query('raw'),

                _fields = {
                    name   = tag.query.name   ('string', 'required'),
                    age    = tag.query.age    ('number', 'required'),
                    reward = tag.query.reward ('number'            ) or 5000,
                }
            }

            -- perform response
            do
                local ljson = require "shared.test.ljson"

                ngx.header.content_type = 'application/json; charset=utf-8'
                ngx.print(ljson.encode(ARGS))
            end
        }
    }
--- request
GET /t?name=luffy&age=19&alias=lucy
--- response_body chomp
{"_fields":{"age":19,"name":"luffy","reward":5000},"_query":{"age":"19","alias":"lucy","name":"luffy"},"_raw":"name=luffy&age=19&alias=lucy"}
--- error_code: 200
--- no_error_log
[error]



=== TEST 2: httparg - validate body
--- http_config eval: $::http_config
--- config
    location = /t {
        content_by_lua_block {
            local tag  = require("shared.httparg").tag()

            local ARGS = {
                -- 取得 args object
                _body = tag.json(),

                -- 取得 args 原始值
                _raw   = tag.text(),

                _fields = {
                    name   = tag.json.name   ('string', 'required'),
                    age    = tag.json.age    ('number', 'required'),
                    reward = tag.json.reward ('number'            ) or 5000,
                }
            }

            -- perform response
            do
                local ljson = require "shared.test.ljson"

                ngx.header.content_type = 'application/json; charset=utf-8'
                ngx.print(ljson.encode(ARGS))
            end
        }
    }
--- request
POST /t
{
  "name": "luffy",
  "age": 19,
  "alias": "lucy"
}
--- response_body chomp
{"_body":{"age":19,"alias":"lucy","name":"luffy"},"_fields":{"age":19,"name":"luffy","reward":5000},"_raw":"{\n  \"name\": \"luffy\",\n  \"age\": 19,\n  \"alias\": \"lucy\"\n}"}
--- error_code: 200
--- no_error_log
[error]



=== TEST 3: httparg - validate header
--- http_config eval: $::http_config
--- config
    location = /t {
        content_by_lua_block {
            local tag  = require("shared.httparg").tag()

            local ARGS = {
                _version = tag.header.version     ('number', 'required'),
            }

            -- perform response
            do
                local ljson = require "shared.test.ljson"

                ngx.header.content_type = 'application/json; charset=utf-8'
                ngx.print(ljson.encode(ARGS))
            end
        }
    }
--- more_headers
Version: 2
--- request
GET /t
--- response_body chomp
{"_version":2}
--- error_code: 200
--- no_error_log
[error]



=== TEST 4-1: httparg - validate multipart (style 1)
--- http_config eval: $::http_config
--- config
    location = /t {
        content_by_lua_block {
            local tag  = require("shared.httparg").tag()

            local ARGS = {
                --驗證該 part 是否存在, 寫法1
                tag.part._arg.validate('required'),

                -- 取得 _provider part 原始值
                _provider_raw = tag.part._provider.text(),
                -- 取得 _arg part 原始值
                _arg_raw      = tag.part._arg.text(),

                -- 取得 _arg part
                _arg    = tag.part._arg.json(),

                _fields = {
                    provider = tag.part._provider        ('string'),
                    name     = tag.part._arg.json.name   ('string', 'required'),
                    age      = tag.part._arg.json.age    ('number', 'required'),
                    reward   = tag.part._arg.json.reward ('number'            ) or 5000,
                }
            }

            -- perform response
            do
                local ljson = require "shared.test.ljson"

                ngx.header.content_type = 'application/json; charset=utf-8'
                ngx.print(ljson.encode(ARGS))
            end
        }
    }
--- more_headers
Content-Type: multipart/mixed; boundary=AaB03x
--- request eval
qq{POST /t
--AaB03x\r
Content-Disposition: form-data; name="_provider"\r
\r
OP\r
--AaB03x\r
Content-Disposition: form-data; name="_arg"\r
Content-Type: application/json; charset=utf-8\r
\r
{"name": "luffy","age": 19,"alias": "lucy"}\r
--AaB03x--\r
}
--- response_body chomp
{"_arg":{"age":19,"alias":"lucy","name":"luffy"},"_arg_raw":"{\"name\": \"luffy\",\"age\": 19,\"alias\": \"lucy\"}","_fields":{"age":19,"name":"luffy","provider":"OP","reward":5000},"_provider_raw":"OP"}
--- error_code: 200
--- no_error_log
[error]



=== TEST 4-2: httparg - validate multipart (style 2)
--- http_config eval: $::http_config
--- config
    location = /t {
        content_by_lua_block {
            local tag  = require("shared.httparg").tag()

            local ARGS = {
                --驗證該 part 是否存在, 寫法2
                tag.validate(
                    tag.part._arg
                )('required'),

                -- 取得 _provider part 原始值
                _provider_raw = tag.part._provider.text(),
                -- 取得 _arg part 原始值
                _arg_raw      = tag.part._arg.text(),

                -- 取得 _arg part
                _arg    = tag.part._arg.json(),

                _fields = {
                    provider = tag.part._provider        ('string'),
                    name     = tag.part._arg.json.name   ('string', 'required'),
                    age      = tag.part._arg.json.age    ('number', 'required'),
                    reward   = tag.part._arg.json.reward ('number'            ) or 5000,
                }
            }

            -- perform response
            do
                local ljson = require "shared.test.ljson"

                ngx.header.content_type = 'application/json; charset=utf-8'
                ngx.print(ljson.encode(ARGS))
            end
        }
    }
--- more_headers
Content-Type: multipart/mixed; boundary=AaB03x
--- request eval
qq{POST /t
--AaB03x\r
Content-Disposition: form-data; name="_provider"\r
\r
OP\r
--AaB03x\r
Content-Disposition: form-data; name="_arg"\r
Content-Type: application/json; charset=utf-8\r
\r
{"name": "luffy","age": 19,"alias": "lucy"}\r
--AaB03x--\r
}
--- response_body chomp
{"_arg":{"age":19,"alias":"lucy","name":"luffy"},"_arg_raw":"{\"name\": \"luffy\",\"age\": 19,\"alias\": \"lucy\"}","_fields":{"age":19,"name":"luffy","provider":"OP","reward":5000},"_provider_raw":"OP"}
--- error_code: 200
--- no_error_log
[error]



=== TEST 4-3: httparg - validate multipart (style 3)
--- http_config eval: $::http_config
--- config
    location = /t {
        content_by_lua_block {
            local tag  = require("shared.httparg").tag()

            local ARGS = {
                --驗證該 part 是否存在, 寫法3
                tag.validate(
                    tag.part._arg,
                    nil
                )('required'),

                -- 取得 _provider part 原始值
                _provider_raw = tag.part._provider.text(),
                -- 取得 _arg part 原始值
                _arg_raw      = tag.part._arg.text(),

                -- 取得 _arg part
                _arg    = tag.part._arg.json(),

                _fields = {
                    provider = tag.part._provider        ('string'),
                    name     = tag.part._arg.json.name   ('string', 'required'),
                    age      = tag.part._arg.json.age    ('number', 'required'),
                    reward   = tag.part._arg.json.reward ('number'            ) or 5000,
                }
            }

            -- perform response
            do
                local ljson = require "shared.test.ljson"

                ngx.header.content_type = 'application/json; charset=utf-8'
                ngx.print(ljson.encode(ARGS))
            end
        }
    }
--- more_headers
Content-Type: multipart/mixed; boundary=AaB03x
--- request eval
qq{POST /t
--AaB03x\r
Content-Disposition: form-data; name="_provider"\r
\r
OP\r
--AaB03x\r
Content-Disposition: form-data; name="_arg"\r
Content-Type: application/json; charset=utf-8\r
\r
{"name": "luffy","age": 19,"alias": "lucy"}\r
--AaB03x--\r
}
--- response_body chomp
{"_arg":{"age":19,"alias":"lucy","name":"luffy"},"_arg_raw":"{\"name\": \"luffy\",\"age\": 19,\"alias\": \"lucy\"}","_fields":{"age":19,"name":"luffy","provider":"OP","reward":5000},"_provider_raw":"OP"}
--- error_code: 200
--- no_error_log
[error]



=== TEST 5: httparg - validate mixed
--- http_config eval: $::http_config
--- config
    location = /t {
        content_by_lua_block {
            local tag  = require("shared.httparg").tag()

            local ARGS = {
                _version     = tag.header.version     ('number', 'required'),

                --驗證該 part 是否存在, 寫法1
                tag.part.source.validate('required'),

                --驗證該 part 是否存在, 寫法2
                tag.validate(
                    tag.part.source,
                    tag.part.other1
                )('required'),

                --驗證該 part 是否存在, 寫法3
                tag.validate(
                    tag.part.source,
                    tag.part.other1,
                    nil
                )('required'),

                source_part  = {
                    provider   = tag.part.source.json.provider ('string', 'required'),
                    server     = tag.part.source.json.server   ('string'),
                },
                provider     = tag.part.other1.json.provider ('string'),
                other        = tag.part.other('string', 'required')
            }

            -- perform response
            do
                local ljson = require "shared.test.ljson"

                ngx.header.content_type = 'application/json; charset=utf-8'
                ngx.print(ljson.encode(ARGS))
            end
        }
    }
--- more_headers
Content-Type: multipart/mixed; boundary=AaB03x
Version: 2
--- request eval
qq{POST /t
--AaB03x\r
Content-Disposition: form-data; name="other1"\r
\r
{\r
    "provider"       : "OP"\r
}\r
--AaB03x\r
Content-Disposition: form-data; name="other"\r
\r
Larry\r
--AaB03x\r
Content-Disposition: form-data; name="source"\r
\r
{\r
  "_version"       : 1,\r
  "server"         : "game.in-addr",\r
  "session"        : "session-12345",\r
  "game"           : "100101800",\r
  "provider"       : "OP",\r
  "player"         : "luffy",\r
  "wallet"         : "wallet_usd",\r
  "currency"       : "USD",\r
  "dealer"         : "PP",\r
  "casino"         : "TW-2228",\r
  "dealerPlayer"   : "8390384",\r
  "account"        : "94528886294",\r
  "accountType"    : "1",\r
  "ip"             : "60.251.71.25",\r
  "ttl"            : 300,\r
  "permissions" : [\r
    "intra-wallet-transfer"\r
  ],\r
  "extraData" : {\r
    "timezone"       : "EST",\r
    "room"           : "1",\r
    "playerDevice"   : "other",\r
    "playerOs"       : "windows"\r
  }\r
}\r
--AaB03x---\r
}
--- response_body chomp
{"_version":2,"other":"Larry","provider":"OP","source_part":{"provider":"OP","server":"game.in-addr"}}
--- error_code: 200
--- no_error_log
[error]



=== TEST 6: httparg - show multipart raw body
--- http_config eval: $::http_config
--- config
    location = /t {
        content_by_lua_block {
            local tag  = require("shared.httparg").tag()

            local ARGS = {
                -- 取得 body 原始值
                _raw = tag.text(),
            }

            -- perform response
            do
                local ljson = require "shared.test.ljson"

                ngx.header.content_type = 'application/json; charset=utf-8'
                ngx.print(ljson.encode(ARGS))
            end
        }
    }
--- more_headers
Content-Type: multipart/mixed; boundary=AaB03x
--- request eval
qq{POST /t
--AaB03x\r
Content-Disposition: form-data; name="_provider"\r
\r
OP\r
--AaB03x\r
Content-Disposition: form-data; name="_arg"\r
Content-Type: application/json; charset=utf-8\r
\r
{"name": "luffy","age": 19,"alias": "lucy"}\r
--AaB03x--\r
}
--- response_body chomp
{"_raw":"--AaB03x\r\nContent-Disposition: form-data; name=\"_provider\"\r\n\r\nOP\r\n--AaB03x\r\nContent-Disposition: form-data; name=\"_arg\"\r\nContent-Type: application/json; charset=utf-8\r\n\r\n{\"name\": \"luffy\",\"age\": 19,\"alias\": \"lucy\"}\r\n--AaB03x--"}
--- error_code: 200
--- no_error_log
[error]


